<?php

namespace App\Entities;

use App\Contracts\GeneratesUniqueHash;
use App\Contracts\HasIdColumn;
use App\Contracts\SystemComponent;
use App\Entities\Base\AbstractEntity;
use App\Entities\Base\User;
use Doctrine\ORM\Mapping as ORM;
use Illuminate\Support\Collection;

/**
 * App\Entities\VulnerabilityHttpData
 *
 * @ORM\Entity(repositoryClass="App\Repositories\VulnerabilityHttpDataRepository")
 * @ORM\Table(name="`vulnerability_http_data`")
 * @ORM\HasLifecycleCallbacks
 */
class VulnerabilityHttpData extends Base\VulnerabilityHttpData implements SystemComponent, HasIdColumn, GeneratesUniqueHash
{
    /** Request type constants */
    const REQUEST_TYPE_GET     = 'GET';
    const REQUEST_TYPE_OPTIONS = 'OPTIONS';
    const REQUEST_TYPE_HEAD    = 'HEAD';
    const REQUEST_TYPE_POST    = 'POST';
    const REQUEST_TYPE_PUT     = 'PUT';
    const REQUEST_TYPE_DELETE  = 'DELETE';
    const REQUEST_TYPE_TRACE   = 'TRACE';
    const REQUEST_TYPE_CONNECT = 'CONNECT';

    /**
     * @ORM\ManyToOne(targetEntity="Vulnerability", inversedBy="vulnerabilityHttpData", cascade={"persist"}, fetch="EAGER")
     * @ORM\JoinColumn(name="`vulnerability_id`", referencedColumnName="`id`", onDelete="CASCADE")
     */
    protected $vulnerability;

    /**
     * @inheritdoc
     *
     * @return User
     */
    public function getUser()
    {
        return $this->vulnerability->getFile()->getUser();
    }

    /**
     * @inheritdoc
     *
     * @param User $user
     * @return $this
     */
    public function setUser(User $user)
    {
        return $this;
    }

    /**
     * @inheritdoc
     *
     * @return Base\File
     */
    public function getParent()
    {
        return $this->vulnerability;
    }

    /**
     * Get a hash value of all the property values whose combination creates a unique key
     *
     * @return string
     */
    public function getHash(): string
    {
        return AbstractEntity::generateUniqueHash($this->getUniqueKeyColumns());
    }

    /**
     * @return Collection
     */
    public function getUniqueKeyColumns(): Collection
    {
        return new Collection([
            parent::HTTP_URI            => $this->http_uri,
            parent::HTTP_METHOD         => $this->http_method,
            parent::HTTP_PORT           => $this->http_port,
            parent::HTTP_STATUS_CODE    => $this->http_status_code,
            parent::HTTP_TEST_PARAMETER => $this->http_test_parameter,
            parent::VULNERABILITY       => $this->vulnerability,
        ]);
    }

    /**
     * Base64 decode the request before returning
     *
     * @return null|string
     */
    public function getHttpRawRequest()
    {
        $decodedRequest = base64_decode(parent::getHttpRawRequest());
        if (empty($decodedRequest)) {
            return null;
        }

        return $decodedRequest;
    }

    /**
     * Base64 decode the response before returning
     *
     * @return null|string
     */
    public function getHttpRawResponse()
    {
        $decodedResponse = base64_decode(parent::getHttpRawResponse());
        if (empty($decodedResponse)) {
            return null;
        }

        return $decodedResponse;
    }

    /**
     * Get the bootstrap CSS class related to the Vulnerabilities severity
     *
     * @return mixed
     */
    public function getBootstrapAlertCssClass()
    {
        return collect([
            self::REQUEST_TYPE_HEAD    => 'info',
            self::REQUEST_TYPE_GET     => 'success',
            self::REQUEST_TYPE_POST    => 'post-request',
            self::REQUEST_TYPE_PUT     => 'warning',
            self::REQUEST_TYPE_DELETE  => 'danger',
            self::REQUEST_TYPE_OPTIONS => 'high',
        ])->get($this->http_method, ',info');
    }
}